home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Tele / C / Comet2.1.3 Folder / Comet / scrinit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-08  |  37.4 KB  |  1,567 lines  |  [TEXT/????]

  1. /*
  2.     Copyright Cornell University 1986.  All rights are reserved.
  3.     
  4.     scrinit.c contains scr_init, which initializes the screen and
  5.     create FONT bitmaps if needed (on the small-screen Mac),
  6.     and a  routine to save the screen location on exit.
  7.  
  8. */
  9.  
  10. #include    <em.h>
  11.  
  12. #include    <h19.h>
  13. #include    <config.h>
  14. #include    <macdefs.h>
  15. #include    <cntldefs.h>
  16. #include    <resdefs.h>
  17.  
  18. FONTS * fontarr[NOATTRS];        /* array of fonts for zapchar */
  19. char * fontskiparr[NOATTRS];        /* array of skip array ptrs for zapbuf */
  20.  
  21. char * strfontbuild = "Using fast-drawing mode; building fonts...";
  22. char * strfonterr = "to build font";            /* memory out error tag */
  23.  
  24. BitMap    copybits;
  25.  
  26. PicHandle iconpict;                /* a little picture of 3270 screen for shrink control */
  27.  
  28. extern savewindpos();            /* forward declaration */
  29.  
  30. /* values saved in refCon for window automatic configuration ... */
  31. #define REFWINDOWSHOW    0x00000001
  32.  
  33.  
  34. /* Initialize the most basic fundaments */
  35.  
  36. scrinit()
  37. {
  38.     register int count;             /* all purpose counter */
  39.     WindowPtr     tempwindow;
  40.     Handle        gdev;            /* handle to graphics devices */
  41.     
  42.     paramptr = GetSysPPtr();    /* user set parameters for blinking */
  43.  
  44.     shrinkpict = GetResource('PICT', (short) 1);
  45.     tapepict = GetResource('PICT', (short) 2);
  46.  
  47.     /* first set the direct to screen table fontskiparr to all 
  48.         skips and then correct so non-blank fonts use skiparr */
  49.     for (count = 0; count < NOATTRS; count++)
  50.         fontskiparr[count] = &allskiparr[0];
  51.     fontskiparr[0] = &skiparr[0];
  52.     fontskiparr[4] = &skiparr[0];
  53.     fontskiparr[8] = &skiparr[0];
  54.     
  55.     /* set up the skip array; only the cases of zero and space are worthwhile */
  56.     skiptest = &skiparr[0];
  57.  
  58.     skiparr[0] = TRUE;
  59.     skiparr[32] = TRUE;
  60.     skiparr[255] = TRUE;
  61.  
  62.     for (count = 0; count < NOCHARS; count++) 
  63.         /* allskiparr is a skiparr which is all true */
  64.         allskiparr[count] = TRUE;
  65.         
  66.  
  67.     iconpict = GetResource('PICT', (short) 0);
  68.  
  69.     exit_hook(savewindpos);    /* add a hook to save the window's position on exit() */
  70.  
  71.     /* updateRgn is used in ScrollRect calls */
  72.     updateRgn = NewRgn();
  73.     emclip = NewRgn();
  74.     q3clip = NewRgn();    
  75.     
  76.     setdragrect();
  77.     
  78. #ifdef USEHELPWINDOW
  79.     buildhelpwindow();
  80.     if (!(helpwindow = GetNewWindow((short) 2, (Ptr) NULL, (WindowPtr) NULL))) {
  81.         error("Can't create help window");
  82.     }
  83. #endif
  84.     return(TRUE);
  85. }
  86.  
  87.  
  88. /* go through list of windows, reset resfile, then save */
  89.  
  90. savewindpos()
  91. {
  92.     struct winds ** conp = conns;
  93.     struct winds * conend = &conp[conncount];
  94.     register struct winds * twp;
  95.     
  96.     while (conp < conend) {
  97.         twp = *conp++;
  98.         if (twp == NULL)
  99.             continue;
  100.                 
  101.         if (twp->emwindow == (WindowPtr) NULL)
  102.             continue;
  103.         
  104.         reopenconfig(twp);
  105.         saveonewindpos(twp);
  106.         closeconfig(twp);
  107.     }
  108.     FlushVol((StringPtr) NULL, (short) twp->resvol);    /* flush the volume */
  109. }
  110.  
  111.  
  112. /*    save the position of the emulator and icon windows into their WIND resources
  113.     so they come up where they were left next time the user launches the program */
  114.     
  115.     
  116. saveonewindpos(conp)
  117. struct winds * conp;
  118. {
  119.     Handle windh;
  120.     Handle iconh;
  121.     Handle texth;
  122.     Handle sizeh;            /* handle to font size resource */
  123.     struct windres * windp;        /* kluge for stupid compiler */
  124.     struct windres * iconp;
  125.     struct windres * textp;
  126.     Point emwpos;
  127.     
  128.     struct windres {
  129.         /* a WIND resource format (IM 1-302) */
  130.  
  131.         short top;
  132.         short left;
  133.         short bottom;
  134.         short right;
  135.         short procID;
  136.         short visible;
  137.         short goaway;
  138.         long refCon;
  139.         short title;            /* actually a Str255 */
  140.     };
  141.  
  142.     sizeh = Get1Resource('Fsiz', (short) 0);
  143.     if (sizeh == NULL) {
  144.         sizeh = NewHandle((long) 2);
  145.         if (sizeh != (Handle) NULL) {
  146.             AddResource(sizeh, 'Fsiz', (short) 0, "\P");
  147.             if (ResError()) {
  148.                 DisposHandle(sizeh);
  149.                 sizeh = NULL;
  150.             }
  151.         }
  152.     }
  153.     if (sizeh != NULL) {
  154.         *((short *) *sizeh) = conp->fontsize;        /* save the font size */
  155.         ChangedResource(sizeh);
  156.     }
  157.  
  158.     windh = Get1Resource('WIND', (short) 0);
  159.     if (windh == NULL) {
  160.         windh = NewHandle((long) sizeof (struct windres));
  161.         if (windh != (Handle) NULL) {
  162.             windp = (struct windres *) *windh;
  163.             memzero(windp, sizeof (struct windres));
  164.             
  165.             AddResource(windh, 'WIND', (short) 0, "\P");
  166.             if (ResError()) {
  167.                 DisposHandle(windh);
  168.                 windh = NULL;
  169.             }
  170.         }
  171.     }
  172.     if (windh != NULL) {
  173.         SetPort(conp->emwindow);
  174.         windp = (struct windres *) *windh;
  175.  
  176.         emwpos.v = -29;         /* -29 (offset) */
  177.         emwpos.h = -10;         /* -10 (offset) */
  178.         LocalToGlobal(&emwpos);
  179.         
  180.         windp->procID = documentProc;
  181.         windp->goaway = 0x0100;
  182.             /* guarantee the window has a go-away box for backward compat */
  183.             
  184.         windp->top = emwpos.v;
  185.         windp->left = emwpos.h;
  186.         windp->bottom = windp->top 
  187.                         + ((GrafPtr) conp->emwindow)->portRect.bottom 
  188.                         - ((GrafPtr) conp->emwindow)->portRect.top;
  189.         windp->right = windp->left 
  190.                         + ((GrafPtr) conp->emwindow)->portRect.right 
  191.                         - ((GrafPtr) conp->emwindow)->portRect.left;
  192.  
  193.         ChangedResource(windh);
  194.     }
  195.     
  196.     iconh = Get1Resource('WIND', (short) 1);
  197.     if (iconh == NULL) {
  198.         iconh = NewHandle((long) sizeof (struct windres));
  199.         if (iconh != (Handle) NULL) {
  200.             iconp = (struct windres *) *iconh;
  201.             memzero(iconp, sizeof (struct windres));
  202.             iconp->procID = plainDBox;
  203.             
  204.             AddResource(iconh, 'WIND', (short) 1, "\P");
  205.             if (ResError()) {
  206.                 DisposHandle(iconh);
  207.                 iconh = NULL;
  208.             }
  209.         }
  210.     }
  211.     if (iconh != NULL) {
  212.         SetPort(conp->iconwindow);
  213.         iconp = (struct windres *) *iconh;
  214.  
  215.         emwpos.v = 0;
  216.         emwpos.h = 0;
  217.         LocalToGlobal(&emwpos);
  218.         
  219.         iconp->top = emwpos.v;
  220.         iconp->left = emwpos.h;
  221.         iconp->bottom = iconp->top 
  222.                         + ((GrafPtr) conp->iconwindow)->portRect.bottom 
  223.                         - ((GrafPtr) conp->iconwindow)->portRect.top;
  224.         iconp->right = iconp->left 
  225.                         + ((GrafPtr) conp->iconwindow)->portRect.right 
  226.                         - ((GrafPtr) conp->iconwindow)->portRect.left;
  227.  
  228.         ChangedResource(iconh);
  229.     }
  230. #ifdef USETEXTWINDOWS
  231.     /* save the text window position */
  232.     texth = Get1Resource('WIND', (short) 2);
  233.     if (texth == NULL) {
  234.         texth = NewHandle((long) sizeof (struct windres));
  235.         if (texth != (Handle) NULL) {
  236.             textp = (struct windres *) *texth;
  237.             memzero(textp, sizeof (struct windres));
  238.             
  239.             AddResource(texth, 'WIND', (short) 2, "\P");
  240.             if (ResError()) {
  241.                 DisposHandle(texth);
  242.                 texth = NULL;
  243.             }
  244.         }
  245.     }
  246.     if (texth != NULL) {
  247.         SetPort(conp->textwindow);
  248.         textp = (struct windres *) *texth;
  249.  
  250.         emwpos.v = 0;
  251.         emwpos.h = 0;
  252.         LocalToGlobal(&emwpos);
  253.         
  254.         textp->procID = documentProc;
  255.         textp->goaway = 0x0100;
  256.             /* guarantee the window has a go-away box for backward compat */
  257.  
  258.         textp->top = emwpos.v;
  259.         textp->left = emwpos.h;
  260.         textp->bottom = textp->top 
  261.                         + ((GrafPtr) conp->textwindow)->portRect.bottom 
  262.                         - ((GrafPtr) conp->textwindow)->portRect.top;
  263.         textp->right = textp->left 
  264.                         + ((GrafPtr) conp->textwindow)->portRect.right 
  265.                         - ((GrafPtr) conp->textwindow)->portRect.left;
  266.  
  267.         if (conp->hidetextwindow)
  268.             /* don't show text window next startup if it's hidden */
  269.             textp->refCon &= ~REFWINDOWSHOW;
  270.         else
  271.             textp->refCon |= REFWINDOWSHOW;
  272.             
  273.         ChangedResource(texth);
  274.     }
  275. #endif
  276.  
  277.     UpdateResFile(conp->resfid);
  278.     FlushVol((StringPtr) NULL, (short) conp->resvol);    /* flush the volume */
  279.     
  280.     if (windh)
  281.         ReleaseResource(windh);
  282.     if (iconh)
  283.         ReleaseResource(iconh);
  284.     if (sizeh)
  285.         ReleaseResource(sizeh);
  286.     
  287. }
  288.  
  289.  
  290. /* set a shield rectangle in global coordinates for suppressing cursor */
  291.  
  292. setshield(twp)
  293. struct winds * twp;
  294. {
  295.     GrafPtr oport;
  296.     
  297.     GetPort(&oport);
  298.     SetPort(twp->emwindow);
  299.     
  300.     /* make the cursor shield test area if we're using direct screen drawing */
  301.     twp->zaprect.top = 0;
  302.     twp->zaprect.left = 0;
  303.     twp->zaprect.bottom = twp->emwindow->portRect.bottom;
  304.     twp->zaprect.right = twp->emwindow->portRect.right;
  305.         /* TODO should use bigrect? */
  306.  
  307.     LocalToGlobal((Point *) &twp->zaprect);
  308.     LocalToGlobal((Point *) &twp->zaprect.bottom);
  309.         /* put the shield rect into global coord for ShieldCursor */
  310.  
  311.     SetPort(oport);
  312. }
  313.  
  314.  
  315. /* build the array of addresses of line starts on the physical screen */
  316.  
  317. setlinestarts(twp)
  318. struct winds * twp;
  319. {
  320.     register unsigned long count;
  321.     register unsigned long offset;
  322.     register short * drawbase;  /* offset from ScrnBase */
  323.     unsigned long rowwords = twp->screenbytes / 2;
  324.     Point point;
  325.     
  326.     /* get the offset from the top left corner of the screen we're on */
  327.     point.h = -10;
  328.     point.v = -29;
  329.     LocalToGlobal(&point);
  330.     point.h -= twp->gdRect.left;
  331.     point.v -= twp->gdRect.top;    
  332.         /* gdRect has the global coordinates of the graphics device */
  333.     
  334.     drawbase = twp->screenbase + 1 
  335.         + (rowwords * SKIPLINES)
  336.         + (twp->voffset * rowwords);
  337.         /* the original origin for zap dsdrawing */
  338.         
  339.     offset = (((point.v  - 20) * rowwords) + (point.h / 16));
  340.         /* offset = number of words =  rows below original zap pos * screenbytes
  341.             + bytes offset from left origin at 0 */
  342.         /* - 20 for offset from original screen vpos */
  343.         
  344.      drawbase += offset;
  345.     
  346.     if (twp->startarr != NULL)
  347.         DisposPtr(twp->startarr);
  348.     twp->startarr = NewPtr((Size) 4 * emdp->linecount);
  349.     if (twp->startarr == NULL) {
  350.         twp->dsdraw = FALSE;
  351.         return(-1);
  352.     }
  353.     
  354.     /* initialize the linestarts screenmap pointer array for zapchar */
  355.     for (count = 0; count <= emdp->lastrow; 
  356.         count++, drawbase += (rowwords * twp->lineheight)) {
  357.  
  358.         *(twp->startarr + count) = drawbase;
  359.     }
  360.     
  361.     return(0);
  362. }
  363.  
  364.  
  365.  
  366. alignwind(twp, moveleft)
  367. struct winds * twp;
  368. int moveleft;
  369. {
  370.     short fraction;
  371.     Point point;
  372.     
  373.     point.h = -10;
  374.     point.v = -29;
  375.     LocalToGlobal(&point);
  376.     fraction = (point.h % 16);
  377.     if (fraction) {
  378.         /* make sure the window is aligned properly */
  379.         if (point.h < 0)
  380.             fraction = -fraction;
  381.         else
  382.             fraction = 16 - fraction;
  383.         
  384.         if (moveleft)
  385.             /* make it hop to the left rather than the right when 
  386.                 user drags to the left */
  387.             fraction -= 16;
  388.  
  389.         /* now get global coordinates */
  390.         point.v = twp->emwindow->portRect.top;
  391.         point.h = twp->emwindow->portRect.left;
  392.         LocalToGlobal(&point);
  393.         
  394.         MoveWindow(twp->emwindow, (short) (point.h + fraction), point.v, (Boolean) FALSE);
  395.     }
  396. }
  397.  
  398. /* TODO use greyRgn? */
  399.  
  400. setdragrect()
  401. {
  402.     dragrect.top = 0;
  403.     dragrect.left = 0;
  404.     dragrect.bottom = 10000;
  405.     dragrect.right = 10000;
  406. }
  407.  
  408.  
  409. testdsall()
  410. {
  411.     /* go through window list and reset dsdraw correctly */
  412.     GrafPtr oport;
  413.     struct winds ** conp = conns;
  414.     struct winds * conend = &conp[conncount];
  415.     struct winds * twp;
  416.     struct winds * oemdp = emdp;
  417.     
  418.     GetPort(&oport);
  419.     
  420.     /* go through window list and try out dsdraw */
  421.     while (conp < conend) {
  422.         twp = *conp++;
  423.         if (twp == NULL || twp->emwindow == NULL)
  424.             continue;
  425.             
  426.         testds(twp);        /* leaves port set to emwindow */
  427.         InvalRect(&twp->bigrect);    /* guarantee it's redrawn */
  428.     }
  429.     SetPort(oport);
  430. }
  431.  
  432.  
  433. /*    Can we use the direct to screen drawing routines? 
  434.     If so, set them up.
  435. */
  436.  
  437. testds(twp)
  438. struct winds * twp;
  439. {
  440.     Rect wrect;
  441.     Rect intersect;
  442.     GDHandle gdev;
  443.     
  444.     SetPort(twp->emwindow);
  445.     colorupd(twp);                /* update colormap */
  446.     if (!trydsdraw 
  447.             || ! (twp->fontwidth == 6 
  448.                 || (twp->fontwidth == 8 && twp->fontheight == 19) )
  449.             || ! (twp->linecount == 24 && twp->linelength == 80)
  450.         ) {
  451.         /* font is not the two sizes currently available,
  452.             or the screen is a non-standard size...
  453.             TODO could other 8 bit wide sizes be supported? 
  454.                     to live dangerously:
  455.                         || twp->linecount > 32 
  456.                         || twp->linelength != 80
  457.             */
  458.         useqd(twp);
  459.         return(FALSE);
  460.     }
  461.     wrect = twp->bigrect;
  462.     LocalToGlobal(&wrect.top);
  463.     LocalToGlobal(&wrect.bottom);
  464.         /* twp->emwindow->portRect was used before the ACTUAL ds area, bigrect, 
  465.                 replaced it.
  466.             wrect is a bit safer but bigrect allows ds drawing on 640 bit wide 
  467.             screens... */
  468.  
  469.     if (environs.hasColorQD) {
  470.         for (gdev = GetDeviceList(); gdev != NULL; gdev = (*gdev)->gdNextGD) {
  471.             if ( ! TestDeviceAttribute(gdev, screenDevice)
  472.                     || ! TestDeviceAttribute(gdev, screenActive) )
  473.                 /* ignore devices which are not active screens */
  474.                 continue;
  475.             if (SectRect(&wrect, &(*gdev)->gdRect, &intersect)) {
  476.                 /* get the intersection of the rectangles */
  477.                 if (EqualRect(&wrect, &intersect)) {
  478.                 /* the intersection == wrect, window is completely in gdevice */
  479.                     if ((*(*gdev)->gdPMap)->pixelSize == 1) {
  480.                         /* we're on a mono screen */
  481.                         /* save globals if this window is the current output window */
  482.                         unsigned long basetemp;
  483.                         
  484.                         if (twp == emdp) {
  485.                             savecontext(emdp);
  486.                         }
  487.                         
  488.                         twp->gdRect = (*gdev)->gdRect;            
  489.                         twp->screenbase = (*(*gdev)->gdPMap)->baseAddr;
  490.                         
  491.                         /* fix mis-advertised NuBus addresses */
  492.                         basetemp = twp->screenbase;
  493.                         if (basetemp & 0xF0000000) {
  494.                             /* the address is on the NuBus */
  495.                             if (! (basetemp & 0x00F00000) ) {
  496.                                 unsigned long theslot;
  497.                                 
  498.                                 /* this NuBus address won't work in 24-bit mode,
  499.                                     we must add the slot# for some Apple boards!
  500.                                     Designing Cards & Drivers 2nd Ed.  p. 90
  501.                                     
  502.                                     $Fs0x xxxx       what some Apple boards give 
  503.                                                      (e.g., 2-page display)
  504.                                     $Fssx xxxx       24 & 32-bit format compatible
  505.                                                      after StripAddress(), since
  506.                                                      900000 -> F9000000 automatically 
  507.                                 */
  508.     
  509.                                 theslot = (basetemp & 0x0F000000) >> 4;
  510.                                 basetemp |= theslot;
  511.                                 twp->screenbase = basetemp;
  512.                             }
  513.                         }
  514.                         /* StripAddress(twp->screenbase); */
  515.                         twp->screenbytes = (*(*gdev)->gdPMap)->rowBytes & 0x0FFF;
  516.                             /* hey, sometimes we get a negative value.  ?!???!
  517.                                 Also, fails to work with E-Machines monitor
  518.                                 4096 * 8 = 32000 ought to be large enough... */
  519.                         twp->screenrem = twp->screenbytes - 64;            /* corrects clrit */    
  520.                         useds(twp);
  521.                         
  522.                         /* update globals if this window is the current output window */
  523.                         if (twp == emdp) {
  524.                             setcontext(emdp);
  525.                         }
  526.                         return(TRUE);
  527.                     }
  528.                     /* the window overlaps; on 512 & 640 screens, try to force? */
  529.                 }
  530.                 break;    /* give up */
  531.             }
  532.         }
  533.         /* hey, we're not anywhere on the screen! */
  534.         useqd(twp);
  535.         return(FALSE);
  536.     }
  537.     else if (screenBits.bounds.right == 512 && twp->fontwidth == 6) {
  538.         /* window is OK if 9 pt. font */
  539.         if (twp == emdp) {
  540.             savecontext(emdp);
  541.         }
  542.         olddsbase(twp);
  543.         useds(twp);
  544.         
  545.         /* update globals if this window is the current output window */
  546.         if (twp == emdp) {
  547.             setcontext(emdp);
  548.         }
  549.         return(TRUE);
  550.     }
  551.     else if (SectRect(&wrect, &screenBits.bounds, &intersect)) {
  552.         if (EqualRect(&wrect, &intersect)) {
  553.             /* window is completely in gdevice */
  554.             if (twp == emdp) {
  555.                 savecontext(emdp);
  556.             }
  557.             
  558.             olddsbase(twp);
  559.             useds(twp);
  560.             
  561.             /* update globals if this window is the current output window */
  562.             if (twp == emdp) {
  563.                 setcontext(emdp);
  564.             }
  565.             return(TRUE);
  566.         }
  567.     }
  568.     useqd(twp);
  569.     return(FALSE);
  570. }
  571.  
  572.  
  573. /* get the offset from the origin of the current window's graphics device */
  574.  
  575. LocalToLocalMap(twp, point)
  576. struct winds * twp;
  577. Point * point;
  578. {
  579.     if (environs.hasColorQD) {
  580.         /* color QD replaces portbits with a PixMap Handle ... */
  581.         point->v = ((GrafPtr) twp->emwindow)->portRect.top 
  582.                 - (* (PixMapHandle) (((GrafPtr) twp->emwindow)->portBits.baseAddr))->bounds.top;
  583.         point->h = ((GrafPtr) twp->emwindow)->portRect.left 
  584.                 - (* (PixMapHandle) (((GrafPtr) twp->emwindow)->portBits.baseAddr))->bounds.left;
  585.     }
  586.     else {
  587.         point->v = ((GrafPtr) twp->emwindow)->portRect.top 
  588.                 - ((GrafPtr) twp->emwindow)->portBits.bounds.top;
  589.         point->h = ((GrafPtr) twp->emwindow)->portRect.left 
  590.                 - ((GrafPtr) twp->emwindow)->portBits.bounds.left;
  591.     }
  592. }
  593.  
  594.  
  595. /* is the top left corner of the window in the display? */
  596.  
  597. indisplay(thewind)
  598. WindowPtr thewind;
  599. {
  600.     Point emwtop;
  601.     GrafPtr oport;
  602.     int retval = FALSE;
  603.     
  604.     GetPort(&oport);
  605.     SetPort(thewind);
  606.     
  607.     if (((WindowPeek) thewind)->windowKind == EMWINDKIND) {
  608.         emwtop.v = -39;
  609.         emwtop.h = 20;
  610.     }
  611.     else {
  612.         emwtop.v = 5;
  613.         emwtop.h = 10;
  614.     }
  615.     
  616.     LocalToGlobal(&emwtop);
  617.         
  618.     if (PtInRgn(pass(emwtop), GetGrayRgn()))
  619.         retval = TRUE;
  620.     else
  621.         retval = FALSE;
  622.         
  623.     SetPort(oport);
  624.     return(retval);
  625. }
  626.  
  627.  
  628. /* build the character tables TODO font size change triggers font rebuild 
  629.     return -1 if can't build font */
  630.  
  631. buildfonts(twp)
  632. struct winds * twp;
  633. {
  634.     WindowPtr     tempwindow;
  635.     GrafPtr oldport;
  636.     int count;
  637.     Rect windRect;
  638.         
  639.     if (twp->fontwidth == 6 && font.font1 != NULL)
  640.         /* already made */
  641.         return(0);
  642.         
  643.     if (twp->fontwidth == 8 && font.font3 != NULL)
  644.         /* already made */
  645.         return(0);
  646.         
  647.     windRect.top = 20;
  648.     windRect.left = 0;
  649.     windRect.bottom = 342;
  650.     windRect.right = 512;
  651.     
  652.     if (TRUE) {
  653.         /* was if (dsdraw) -- make all the special direct-to-screen fonts */
  654.         
  655.         GetPort(&oldport);
  656.         if (!(tempwindow = NewWindow((Ptr) NULL, &windRect, "\P", 
  657.             (Boolean) FALSE, (short) 0, (WindowPtr) NULL, (Boolean) 0, 0L))) {
  658.             SetPort(oldport);
  659.             return(-1);
  660.         }
  661.         SetPort(tempwindow);
  662.     
  663.         if (twp->fontwidth == 6) {
  664.             /* build the 9 pt fonts */
  665.             
  666. #ifndef MERGEDVTCHARS
  667.             if (!memtest((long) 6 * 2 * (2 * NOCHARS * 12), strfonterr)) {
  668.                 /* not enough memory for operation, which is 72K */
  669.                 return(-1);
  670.             }
  671. #else
  672.             if (!memtest((long) 4 * 2 * (2 * NOCHARS * 12), strfonterr)) {
  673.                 /* not enough memory for operation, which is 72K */
  674.                 return(-1);
  675.             }
  676. #endif
  677.             fixgrafport(6, 12);
  678.             
  679.             prerr25(strfontbuild);
  680.             if (
  681.                     buildfont(&font, twp->normfont, 9, 9, 12, 6, FALSE)
  682.                 || buildfont(&invfont, twp->normfont, 9, 9, 12, 6, TRUE)    
  683.                 || buildfont(&boldfont, twp->highfont, 9, 9, 12, 6, FALSE)
  684.                 || buildfont(&invboldfont, twp->highfont, 9, 9, 12, 6, TRUE)
  685. #ifndef MERGEDVTCHARS
  686.                 || buildfont(&bvtfont, twp->vtfont, 9, 9, 12, 6, FALSE)
  687.                 || buildfont(&invbvtfont, twp->vtfont, 9, 9, 12, 6, TRUE)
  688. #endif
  689.                 
  690.             ) {
  691.                 freefont(6);
  692.                 return(-1);
  693.             }
  694.             
  695.             chofftab9 = NewPtr((Size) (2 * NOCHARS));
  696.             if (chofftab9 == NULL) {
  697.                 freefont(6);
  698.                 return(-1);
  699.             }
  700.  
  701.             for (count = 0; count < NOCHARS; count++) {
  702.                 *(chofftab9 + count) = count * 2 * 12;
  703.             }
  704.         }
  705.         else if (twp->fontwidth == 8) {
  706.             /* build the 19 pt font, used to do 14 pt */
  707. #ifndef MERGEDVTCHARS
  708.             if (!memtest((long) 6 * (2 * NOCHARS * 19), strfonterr)) {
  709.                 /* not enough memory for operation, which is 45K */
  710.                 return(-1);
  711.             }
  712. #else
  713.             if (!memtest((long) 4 * (2 * NOCHARS * 19), strfonterr)) {
  714.                 /* not enough memory for operation, which is 45K */
  715.                 return(-1);
  716.             }
  717. #endif
  718.             
  719.             fixgrafport(8, 19);
  720.             
  721.             prerr25(strfontbuild);
  722.             /* was 14, 12, 14, for 14 point font */
  723.             if (
  724.                     buildfont(&font, twp->normfont, 16, 14, 19, 8, FALSE)
  725.                 || buildfont(&invfont, twp->normfont, 16, 14, 19, 8, TRUE)
  726.                 || buildfont(&boldfont, twp->highfont, 16, 14, 19, 8, FALSE)
  727.                 || buildfont(&invboldfont, twp->highfont, 16, 14, 19, 8, TRUE)
  728. #ifndef MERGEDVTCHARS
  729.                 || buildfont(&bvtfont, twp->vtfont, 16, 14, 19, 8, FALSE)
  730.                 || buildfont(&invbvtfont, twp->vtfont, 16, 14, 19, 8, TRUE)
  731. #endif
  732.             ) {
  733.                 freefont(8);
  734.                 return(-1);
  735.             }
  736.         
  737.             chofftab12 = NewPtr((Size) (2 * NOCHARS));
  738.             if (chofftab12 == NULL){
  739.                 freefont(8);
  740.                 return(-1);
  741.             }
  742.                 
  743.             for (count = 0; count < NOCHARS; count++) {
  744.                 *(chofftab12 + count) = count * 2 * 19;
  745.             }
  746.         }
  747.         else
  748.             return(-1);
  749.     
  750.         thefont = &font;
  751.  
  752.         /* load the font array for zapline; only 0, 4, & 8 are really defined */
  753.         fontarr[0] = &font;
  754.         fontarr[4] = &font;
  755.         fontarr[8] = &boldfont;
  756.  
  757.         DisposeWindow(tempwindow);
  758.         DisposPtr(copybits.baseAddr);
  759.  
  760.         SetPort(oldport);
  761.     }
  762.     return(0);
  763. }
  764.  
  765.  
  766.  
  767. buildfont(fontp, fontid, fontsize, fontascent, fontheight, fontwidth, invert)
  768. FONTS * fontp;
  769. short fontid;
  770. int fontsize;
  771. int fontascent;
  772. int fontheight;
  773. int fontwidth;
  774. int invert;
  775. {
  776.     register unsigned short *iptr;    /* -> bitmap char image from DrawChar */
  777.     register unsigned short *iptr1;    /* -> FONT1 char images */
  778.     register unsigned short *iptr2;    /* -> FONT2 char images */
  779.     short thechar;
  780.     int count;
  781.     Rect invrect;
  782.     
  783.     /* Make the inverted normal font */
  784.     if (fontwidth == 6) {
  785.         if (fontp->font1) {
  786.             /* free the existing version */
  787.             DisposPtr(fontp->font1);
  788.             DisposPtr(fontp->font2);
  789.         }
  790.         iptr1 = fontp->font1 = (unsigned short *) NewPtr((Size) (2 * NOCHARS * fontheight));
  791.         iptr2 = fontp->font2 = (unsigned short *) NewPtr((Size) (2 * NOCHARS * fontheight));
  792.         if (iptr1 == NULL || iptr2 == NULL) {
  793.             return(-1);
  794.         }
  795.     }
  796.     else if (fontwidth == 8) {
  797.         if (fontp->font3) {
  798.             /* free the existing version */
  799.             DisposPtr(fontp->font3);
  800.         }
  801.         iptr1 = fontp->font3 = (unsigned short *) NewPtr((Size) (2 * NOCHARS * fontheight));
  802.         if (iptr1 == NULL) {
  803.             return(-1);
  804.         }
  805.     }
  806.  
  807.     
  808.     TextFont(fontid);
  809.     TextSize((short) fontsize);
  810.         
  811.     invrect.top = 0;
  812.     invrect.left = 0;
  813.     invrect.bottom = fontheight;
  814.     invrect.right = fontwidth;
  815.  
  816.     EraseRect(&thePort->portBits.bounds);
  817.     if (fontwidth == 6) {
  818.         for (thechar = 0; thechar < NOCHARS; thechar++) {
  819.             /* clear the bitmap  and draw the next character                */
  820.             MoveTo((short) 0, (short) fontascent); 
  821.             EraseRect(&invrect);
  822.             DrawChar((char) thechar);
  823.             if (invert)
  824.                 InvertRect(&invrect);
  825.     
  826.             iptr = thePort->portBits.baseAddr;
  827.             for (count = 0; count < fontheight; count++)    {
  828.                 *iptr2++ = *iptr;
  829.                 *iptr1++ = *iptr++ >> 2;
  830.             }
  831.         }
  832.     }
  833.     else if (fontwidth == 8) {
  834.         for (thechar = 0; thechar < NOCHARS; thechar++) {
  835.             /* clear the bitmap  and draw the next character                */
  836.             MoveTo((short) 0, (short) fontascent); 
  837.             EraseRect(&invrect);
  838.             DrawChar((char) thechar);
  839.             if (invert)
  840.                 InvertRect(&invrect);
  841.     
  842.             iptr = thePort->portBits.baseAddr;
  843.             for (count = 0; count < fontheight; count++)    {
  844.                 *iptr1++ = *iptr++;
  845.             }
  846.         }
  847.     }
  848.     return(0);
  849. }
  850.  
  851.  
  852. /* free the storage associated with a (half-built) font */
  853.  
  854. freefont(fontwidth)
  855. short fontwidth;
  856. {
  857.     if (fontwidth == 6) {
  858.         if (font.font1)            DisposPtr(font.font1);
  859.         if (font.font2)            DisposPtr(font.font2);
  860.         if (invfont.font1)        DisposPtr(invfont.font1);
  861.         if (invfont.font2)        DisposPtr(invfont.font2);
  862.         if (boldfont.font1)        DisposPtr(boldfont.font1);
  863.         if (boldfont.font2)        DisposPtr(boldfont.font2);
  864.         if (invboldfont.font1)    DisposPtr(invboldfont.font1);
  865.         if (invboldfont.font2)    DisposPtr(invboldfont.font2);
  866.         if (bvtfont.font1)        DisposPtr(bvtfont.font1);
  867.         if (bvtfont.font2)        DisposPtr(bvtfont.font2);
  868.         if (invbvtfont.font1)    DisposPtr(invbvtfont.font1);
  869.         if (invbvtfont.font2)    DisposPtr(invbvtfont.font2);
  870.  
  871.         font.font1 = NULL;
  872.         font.font2 = NULL;
  873.         invfont.font1 = NULL;
  874.         invfont.font2 = NULL;
  875.         boldfont.font1 = NULL;
  876.         boldfont.font2 = NULL;
  877.         invboldfont.font1 = NULL;
  878.         invboldfont.font2 = NULL;
  879.         bvtfont.font1 = NULL;
  880.         bvtfont.font2 = NULL;
  881.         invbvtfont.font1 = NULL;
  882.         invbvtfont.font2 = NULL;
  883.     }
  884.     if (fontwidth == 8) {
  885.         if (font.font3)            DisposPtr(font.font3);
  886.         if (invfont.font3)        DisposPtr(invfont.font3);
  887.         if (boldfont.font3)        DisposPtr(boldfont.font3);
  888.         if (invboldfont.font3)    DisposPtr(invboldfont.font3);
  889.         if (bvtfont.font3)        DisposPtr(bvtfont.font3);
  890.         if (invbvtfont.font3)    DisposPtr(invbvtfont.font3);
  891.  
  892.         font.font3 = NULL;
  893.         invfont.font3 = NULL;
  894.         boldfont.font3 = NULL;
  895.         invboldfont.font3 = NULL;
  896.         bvtfont.font3 = NULL;
  897.         invbvtfont.font3 = NULL;
  898.     }
  899.     error("Not enough memory to build direct-to-screen font");
  900. }
  901.  
  902.  
  903. /* move the controls on the right hand side of the window out from their
  904.     default size */
  905.  
  906. screxpand()
  907. {
  908.     int dv;
  909.     int dh;
  910.     int emv;                /* emulator height */
  911.     int emh;                /* emulator width */
  912.  
  913.     /*
  914.         480, 288 original 9 pt dimensions
  915.         + 29, + 30 for controls & stuff
  916.     */
  917.     
  918.     emh = (emdp->lastcol + 1) * emdp->fontwidth + 2 * emdp->hoffset;
  919.     dh = emh - 480;
  920.     
  921.     emv = (emdp->lastrow + 1) * emdp->lineheight + emdp->voffset;
  922.     dv = emv - 288;
  923.     
  924.     prettyresize(dh, dv);
  925.     SizeWindow(emwindow, (short) 509 + dh, (short) 318 + dv, (Boolean) FALSE);
  926.  
  927. #ifndef SIZETEXTWINDOW
  928.     textwsize(emh + 28, emv);
  929. #endif
  930. }
  931.  
  932.  
  933.  
  934. /* create a new window & accompanying iconwindow
  935.     sets globals 
  936. */
  937.  
  938. char * makewinderr = "Not enough memory to make a window";
  939.  
  940. makewind()
  941. {
  942.     WindowPtr emw;                /* -> emulator windowptr */
  943.     WindowPtr iconw;                /* -> icon windowptr */
  944.     WindowPtr textw;                /* -> icon windowptr */
  945.     GrafPtr oldport;
  946.  
  947.     if (!memtest((long) (3 * sizeof(WindowRecord) + 
  948.             (2 * emdp->linelength * emdp->linecount) ), "to make window")) {
  949.         return(-1);
  950.     }
  951.     GetPort(&oldport);
  952.     if ((emdp->sel_tm = tm_alloc()) == NULL) {
  953.         error(makewinderr);
  954.         return(-1);
  955.     }
  956.     if ((emdp->timer25 = tm_alloc()) == NULL) {
  957.         error(makewinderr);
  958.         return(-1);
  959.     }
  960. #ifdef USETEXTWINDOWS
  961.     if (!(textw = GetNewWindow((short) 2, (Ptr) NULL, (WindowPtr) -1L))) {
  962.         SetPort(oldport);
  963.         error(makewinderr);
  964.         return(-1);
  965.     }
  966. #endif
  967.     if (environs.hasColorQD) {
  968.         if (!(iconw = GetNewCWindow((short) 1, (Ptr) NULL, (WindowPtr) NULL))) {
  969.             SetPort(oldport);
  970.             error(makewinderr);
  971.             return(-1);
  972.         }
  973.         if (!(emw = GetNewCWindow((short) 0, (Ptr) NULL, (WindowPtr) -1L))) {
  974.             DisposeWindow(iconw);
  975.             SetPort(oldport);
  976.             error(makewinderr);
  977.             return(-1);
  978.         }
  979.     }
  980.     else {
  981.         if (!(iconw = GetNewWindow((short) 1, (Ptr) NULL, (WindowPtr) NULL))) {
  982.             SetPort(oldport);
  983.             error(makewinderr);
  984.             return(-1);
  985.         }
  986.         if (!(emw = GetNewWindow((short) 0, (Ptr) NULL, (WindowPtr) -1L))) {
  987.             DisposeWindow(iconw);
  988.             SetPort(oldport);
  989.             error(makewinderr);
  990.             return(-1);
  991.         }
  992.         emdp->color = FALSE;
  993.     }
  994.  
  995.     emdp->emwindow = emw;
  996.     emdp->iconwindow = iconw;
  997.  
  998.     emwindow = emw;                /* set globals */
  999.     iconwindow = iconw;
  1000.     
  1001.     ((WindowPeek) emw)->refCon = emdp;
  1002.     ((WindowPeek) iconw)->refCon = emdp;
  1003.         /* refcon points back to our connection structure */
  1004.  
  1005.     ((WindowPeek) emw)->windowKind = EMWINDKIND;
  1006.     ((WindowPeek) iconw)->windowKind = ICONWINDKIND;
  1007.  
  1008. #ifdef USETEXTWINDOWS
  1009.     emdp->textwindow = textw;
  1010.     if (((WindowPeek) textw)->refCon & REFWINDOWSHOW)
  1011.         /* hide the text window unless it's been brought up before... */
  1012.         emdp->hidetextwindow = FALSE;
  1013.     else
  1014.         emdp->hidetextwindow = TRUE;
  1015.         
  1016.     ((WindowPeek) textw)->refCon = emdp;
  1017.     ((WindowPeek) textw)->windowKind = TEXTWINDKIND;
  1018. #endif
  1019.  
  1020.     SetPort(iconw);
  1021.     TextSize(9);
  1022.     /* position the iconwindow... this is a bit bogus since it will always haul 
  1023.         the icons onto the Main Screen (with the menus) or is it bogus? */
  1024.     
  1025.     if ( !indisplay(iconwindow)) {
  1026.         /* move the iconwindow to the bottom right if it hasn't been moved before 
  1027.             or is out of sight */
  1028.         MoveWindow(iconwindow, (short) (screenBits.bounds.right - 60), 
  1029.             (short) (screenBits.bounds.bottom - 140 + conncount * 10), (Boolean) 0);
  1030.     }
  1031.     
  1032.     
  1033.     SetPort(emw);
  1034.     
  1035.     initwind();
  1036.     
  1037.     /* adjust margins */
  1038.     SetOrigin((short) -10, (short) -29); 
  1039.         /* for zapchar, 
  1040.             h = 1 word - 6 bits over, 
  1041.             v = SKIPLINES - windRect.top */ 
  1042.  
  1043.     TextFont(emdp->highfont);                    /* make bold font the default */
  1044.     TextSize((short) 9);
  1045.     TextMode(srcCopy);                    /* copy mode will obliterate w/o erase */
  1046.  
  1047.     builddiacritics();            /* only needed once, but must be done in 
  1048.                                     window context or Finder gets screwed up! */
  1049.     
  1050.     /* move & resize the window if necessary */
  1051.     
  1052.     SizeWindow(emw, (short) 509, (short) 318, (Boolean) FALSE);
  1053. #ifdef USETEXTWINDOWS
  1054. #ifndef SIZETEXTWINDOW
  1055.     SizeWindow(textw, (short) 509, (short) 298, (Boolean) FALSE);
  1056.         /* make all windows start out small... */
  1057. #endif
  1058. #endif
  1059.  
  1060.     prettyinit();
  1061.     
  1062.     setfontsize(emdp->fontsize);
  1063.  
  1064. #ifdef USETEXTWINDOWS
  1065.     textwinit();
  1066. #else
  1067.     emdp->textwindow = -1;            /* make sure it can never be == FrontWindow */
  1068. #endif
  1069.  
  1070.     screxpand();
  1071.     alignwind(emdp, FALSE);
  1072.     
  1073.     if (windtightfit(emdp) || !indisplay(emwindow) ) {
  1074.         /* if the window is not in the display, move if it necessary */
  1075.         fitwindow(emdp);
  1076.     }
  1077.  
  1078.  
  1079.     ClipRect(&((GrafPtr) emw)->portRect);        /* make the clip rect smaller so small macs do diffrgn ok */
  1080.     
  1081.     controlinit(emw, emdp->ibm_keymode ? IBMRES : ASCRES);    /* TODO delete? */
  1082.  
  1083.     pr25(0, nosessionstr);    /* no session exists */
  1084.     ShowWindow(emw);
  1085.  
  1086. #ifdef USETEXTWINDOWS
  1087.     if (!emdp->hidetextwindow)
  1088.         ShowWindow(textw);        /* leave hidden if not saved as visible! */
  1089. #endif
  1090.  
  1091.     setcontext(emdp);        /* update globals before testds does savecontext() */
  1092.     
  1093.     testds(emdp);
  1094.     if (emdp->hhostname) {
  1095.         HLock(emdp->hhostname);
  1096.         windowtitle(emdp, *emdp->hhostname);
  1097.         HUnlock(emdp->hhostname);
  1098.     }
  1099.  
  1100. }
  1101.  
  1102.  
  1103. /* free the window and storage associated with it */
  1104.  
  1105. killwind(twp)
  1106. struct winds * twp;
  1107. {
  1108.     
  1109.     if (twp->startarr != NULL)
  1110.         DisposPtr(twp->startarr);
  1111.  
  1112.     tm_clear(twp->sel_tm);
  1113.     tm_free(twp->sel_tm);
  1114.     
  1115.     tm_clear(twp->timer25);
  1116.     tm_free(twp->timer25);
  1117.     
  1118.     killcontrols(twp->emwindow);
  1119.     DisposeWindow(twp->emwindow);
  1120.     DisposeWindow(twp->iconwindow);
  1121.  
  1122. #ifdef USETEXTWINDOWS
  1123.     /* release text window */
  1124.     TEDispose(twp->texthand);
  1125.     KillControls(twp->textwindow);
  1126.     DisposeWindow(twp->textwindow);
  1127.     twp->textwindow = NULL;
  1128. #endif
  1129.     killwindmenu(twp->emwindow);
  1130.     
  1131.     if (twp->emwindow == keydp->emwindow) {
  1132.         keydp->emwindow = NULL;
  1133.         keywindow = NULL;
  1134.     }
  1135.  
  1136.     twp->emwindow = NULL;
  1137.     twp->iconwindow = NULL;
  1138.     
  1139.     InitCursor();        /* guarantee that the cursor is a visible arrow */
  1140. }
  1141.  
  1142.  
  1143.  
  1144. initwind()
  1145. {
  1146.     /* set the size of the bigrect erase rectangle */
  1147.     emdp->bottommarg = BOTTOMMARG;            /* bottom margin of emulator area */
  1148.     emdp->rightmarg = RIGHTMARG;            /* right margin of emulator area */        
  1149.     emdp->mrecttop = MRECTTOP;                /* offset to top of mouse tracking rectangle */
  1150.     emdp->mrectbot = MRECTBOT;                /* offset to bottom of mouse tracking */
  1151.     
  1152.     emdp->bigrect.top = TOPMARG;
  1153.     emdp->bigrect.left = LEFTMARG;
  1154.     emdp->bigrect.bottom = BOTTOMMARG;
  1155.     emdp->bigrect.right = RIGHTMARG;
  1156.  
  1157.     emdp->thefont = &font;                    /* default font */
  1158.     
  1159.     emdp->curstop = CURSTOP;                /* top of the cursor */
  1160.     
  1161.     /* use vt100 by default */
  1162.  
  1163.     emdp->em = vt100;
  1164.     emdp->emstr = vt100str;
  1165.  
  1166.     vt100reset();
  1167.  
  1168.     return(0);                /* all is cool */
  1169. }
  1170.  
  1171. /* free the ASCII emulator memory */
  1172.  
  1173. ascii_free(twp)
  1174. struct winds * twp;
  1175. {
  1176.     if (twp->charr)
  1177.         DisposPtr(twp->charr);
  1178.     if (twp->tabset)
  1179.         DisposPtr(twp->tabset);
  1180. }
  1181.  
  1182. /* OK to use screenbits */
  1183.  
  1184. olddsbase(twp)
  1185. struct winds * twp;
  1186. {
  1187.     twp->screenbase = (short *) *ScrnBase;
  1188.     twp->screenbytes = screenBits.rowBytes & 0x7FFF;
  1189.     twp->screenrem = screenbytes - 64;            /* corrects clrit */    
  1190. }
  1191.  
  1192.  
  1193.  
  1194. /*    center the window in the middle of the screen
  1195.     window is hidden so we show it 
  1196.     
  1197. */
  1198.  
  1199. centerwind(windp)
  1200. WindowPtr windp;
  1201. {
  1202.     Point pos;
  1203.     Point emwpos;
  1204.     GrafPtr topemwind;
  1205.     
  1206.     SetPort(windp);
  1207.     pos.v = 0;
  1208.     pos.h = 0;
  1209.     
  1210.     if (keywindow == NULL) {
  1211.         ShowWindow(windp);
  1212.         return;
  1213.     }
  1214.         
  1215.     LocalToGlobal(&pos);
  1216.  
  1217.     /* get original emwindow global coordinates */
  1218.     topemwind = keydp->emwindow;
  1219.     SetPort(topemwind);
  1220.     emwpos.v = -49;         /* -29 (offset) - 20 (original global window top) */
  1221.     emwpos.h = -10;         /* -10 (offset) */
  1222.  
  1223.     /* re-center the window over the main screen */
  1224.     emwpos.v = (screenBits.bounds.bottom - screenBits.bounds.top - 342) / 3;
  1225.     emwpos.h = (screenBits.bounds.right - screenBits.bounds.left - 512) / 2;
  1226.  
  1227.     MoveWindow(windp, pos.h + emwpos.h, pos.v + emwpos.v, (Boolean) 0);
  1228.  
  1229.     ShowWindow(windp);
  1230.     SetPort(windp);
  1231. }
  1232.  
  1233.  
  1234. /*    center the window over the current emwindow; windows are already placed 
  1235.     so they look good over standard window, so just shift 'em 
  1236.     window is hidden so we show it 
  1237.     
  1238. */
  1239.  
  1240. overwind(windp)
  1241. WindowPtr windp;
  1242. {
  1243.     Point pos;
  1244.     Point emwpos;
  1245.     GrafPtr topemwind;
  1246.     
  1247.     SetPort(windp);
  1248.     pos.v = 0;
  1249.     pos.h = 0;
  1250.     
  1251.     if (keywindow == NULL) {
  1252.         ShowWindow(windp);
  1253.         return;
  1254.     }
  1255.         
  1256.     LocalToGlobal(&pos);
  1257.  
  1258.     /* get original emwindow global coordinates */
  1259.     topemwind = keydp->emwindow;
  1260.     SetPort(topemwind);
  1261.     emwpos.v = -49;         /* -29 (offset) - 20 (original global window top) */
  1262.     emwpos.h = -10;         /* -10 (offset) */
  1263.  
  1264.     /* re-center the window (dialog, what have you) over the top window */
  1265.     emwpos.v += (topemwind->portRect.bottom - topemwind->portRect.top - 318) / 2;
  1266.     emwpos.h += (topemwind->portRect.right - topemwind->portRect.left - 509) / 2;
  1267.  
  1268.     LocalToGlobal(&emwpos);
  1269.     
  1270.     MoveWindow(windp, pos.h + emwpos.h, pos.v + emwpos.v, (Boolean) 0);
  1271.  
  1272.     ShowWindow(windp);
  1273.     SetPort(windp);
  1274. }
  1275.  
  1276.  
  1277. /* move the point from fixed global pos to one over the current topemwind */
  1278.  
  1279. centerpoint(thept)
  1280. Point * thept;
  1281. {
  1282.     GrafPtr oport;
  1283.     Point emwpos;
  1284.     GrafPtr topemwind;
  1285.     
  1286.     if (keywindow == NULL)
  1287.         return;
  1288.         
  1289.     GetPort(&oport);
  1290.     
  1291.     /* get original emwindow global coordinates */
  1292.     topemwind = keydp->emwindow;
  1293.     SetPort(topemwind);
  1294.     emwpos.v = -49;         /* -29 (offset) - 20 (original global window top) */
  1295.     emwpos.h = -10;         /* -10 (offset) */
  1296.  
  1297. #ifdef CENTEROVER
  1298.     /* re-center it over the top window */
  1299.     emwpos.v += (topemwind->portRect.bottom - topemwind->portRect.top - 318) / 2;
  1300.     emwpos.h += (topemwind->portRect.right - topemwind->portRect.left - 509) / 2;
  1301.  
  1302.     LocalToGlobal(&emwpos);
  1303.  
  1304. #else
  1305. /* the more standard way of doing it... */
  1306.     /* re-center the window over the main screen */
  1307.  
  1308.     emwpos.v = (screenBits.bounds.bottom - screenBits.bounds.top - 342) / 3;
  1309.     emwpos.h = (screenBits.bounds.right - screenBits.bounds.left - 512) / 2;
  1310.  
  1311. #endif
  1312.  
  1313.     thept->v += emwpos.v;
  1314.     thept->h += emwpos.h;
  1315.     
  1316.     SetPort(oport);
  1317. }
  1318.  
  1319.  
  1320. /* dialog for user to OK saving a resource which has been modified */
  1321.  
  1322. doconfig()
  1323. {
  1324.     return(TRUE);
  1325. }
  1326.  
  1327.  
  1328.  
  1329. fixgrafport(width, height)
  1330. short width;
  1331. short height;
  1332. {
  1333.     /* set up the BitMap used in copying the fonts to our buffers            */
  1334.     Rect cliprect;
  1335.  
  1336.     copybits.baseAddr = (QDPtr) NewPtr((Size) 2 * 48);
  1337.     copybits.rowBytes = 2;
  1338.     copybits.bounds.top = 0;
  1339.     copybits.bounds.left = 0;
  1340.     copybits.bounds.bottom = height;
  1341.     copybits.bounds.right = 16;
  1342.  
  1343.     if (copybits.baseAddr == NULL)
  1344.         return(-1);
  1345.         
  1346.     SetPortBits(©bits); 
  1347.  
  1348.     /* correct visRgn and clipRgn to allow drawing */
  1349.     RectRgn(thePort->visRgn, ©bits.bounds);
  1350.     cliprect.top = 0;
  1351.     cliprect.left = 0;
  1352.     cliprect.bottom = copybits.bounds.bottom;
  1353.     cliprect.right = copybits.bounds.right; 
  1354.     ClipRect(&cliprect);
  1355.  
  1356.     /* set port size so right margin is big enough */
  1357.     PortSize(copybits.bounds.right, copybits.bounds.bottom);
  1358.  
  1359. }
  1360.  
  1361.  
  1362. /* put the window in an appropriate place if it somehow got somewhere 
  1363.     inappropriate */
  1364.  
  1365. fitwindow(twp)
  1366. struct winds * twp;
  1367. {
  1368.     if (twp->gdRect.right == 512) {
  1369.         if (twp->gdRect.bottom > 348) {
  1370.             /* same width but larger than original screen */
  1371.             MoveWindow(twp->emwindow, (short) 0, (short) 36, (Boolean) 0);
  1372. #ifdef USETEXTWINDOWS
  1373.             MoveWindow(twp->textwindow, (short) 0, (short) 55, (Boolean) 0);
  1374. #endif
  1375.         }
  1376.         else {
  1377.             /* make sure window OK on small mac screen */
  1378.             MoveWindow(twp->emwindow, (short) 0, (short) 20, (Boolean) 0);
  1379. #ifdef USETEXTWINDOWS
  1380.             MoveWindow(twp->textwindow, (short) 0, (short) 43, (Boolean) 0);
  1381. #endif
  1382.         }
  1383.     }
  1384.     else if (twp->gdRect.right == 640) {
  1385.         /* 13" color monitor and Portrait Display */
  1386.         if (emdp->fontsize == 14) {
  1387.             /* make sure window fits and runs DS on a 640 wide screen */
  1388.             MoveWindow(twp->emwindow, (short) -16, (short) 36, (Boolean) 0);
  1389. #ifdef USETEXTWINDOWS
  1390.             MoveWindow(twp->textwindow, (short) 0, (short) 55, (Boolean) 0);
  1391. #endif
  1392.         }
  1393.         else if (emdp->fontsize == 16) {
  1394.             if (twp->gdRect.bottom <= 525) {
  1395.                 /* make sure window fits and runs DS on a 640 wide X 512 V screen */
  1396.                 MoveWindow(twp->emwindow, (short) -16, (short) -9, (Boolean) 0);
  1397. #ifdef USETEXTWINDOWS
  1398.                 MoveWindow(twp->textwindow, (short) -6, (short) 14, (Boolean) 0);
  1399. #endif
  1400.             }
  1401.             else {
  1402.                 /* make sure window fits and runs DS on a 640 wide screen */
  1403.                 MoveWindow(twp->emwindow, (short) -16, (short) 36, (Boolean) 0);
  1404. #ifdef USETEXTWINDOWS
  1405.                 MoveWindow(twp->textwindow, (short) -6, (short) 55, (Boolean) 0);
  1406. #endif
  1407.             }
  1408.         }
  1409.         else {
  1410.             MoveWindow(twp->emwindow, (short) 0, (short) 36, (Boolean) 0);
  1411. #ifdef USETEXTWINDOWS
  1412.             MoveWindow(twp->textwindow, (short) 0, (short) 55, (Boolean) 0);
  1413. #endif
  1414.         }
  1415.     }
  1416.     else {
  1417.         MoveWindow(twp->emwindow, (short) 0, (short) 36, (Boolean) 0);
  1418. #ifdef USETEXTWINDOWS
  1419.         MoveWindow(twp->textwindow, (short) 0, (short) 55, (Boolean) 0);
  1420. #endif
  1421.     }
  1422. }
  1423.  
  1424.  
  1425.  
  1426. setgdrect(twp)
  1427. struct winds * twp;
  1428. {
  1429.     Rect wrect;
  1430.     Rect intersect;
  1431.     GDHandle gdev;
  1432.     Point emwtop;
  1433.     
  1434.     SetPort(twp->emwindow);
  1435.     wrect = twp->bigrect;
  1436.     LocalToGlobal(&wrect.top);
  1437.     LocalToGlobal(&wrect.bottom);
  1438.  
  1439.     if (environs.hasColorQD) {
  1440.         /* make the screen which contains the upper left corner the home screen */
  1441.         emwtop.v = -39;
  1442.         emwtop.h = 20;
  1443.         LocalToGlobal(&emwtop);
  1444.         for (gdev = GetDeviceList(); gdev != NULL; gdev = (*gdev)->gdNextGD) {
  1445.             if ( ! TestDeviceAttribute(gdev, screenDevice)
  1446.                     || ! TestDeviceAttribute(gdev, screenActive) )
  1447.                 /* ignore devices which are not active screens */
  1448.                 continue;
  1449.             if (PtInRect(pass(emwtop), &(*gdev)->gdRect)) {
  1450.                 /* the first device with an intersection is the winner */
  1451.                 twp->gdRect = (*gdev)->gdRect;            
  1452.                 return;
  1453.             }
  1454.         }
  1455.         /* if we reach here the point was off the screen, so we will look for
  1456.             any intersection... */
  1457.         for (gdev = GetDeviceList(); gdev != NULL; gdev = (*gdev)->gdNextGD) {
  1458.             if ( ! TestDeviceAttribute(gdev, screenDevice)
  1459.                     || ! TestDeviceAttribute(gdev, screenActive) )
  1460.                 /* ignore devices which are not active screens */
  1461.                 continue;
  1462.             if (SectRect(&wrect, &(*gdev)->gdRect, &intersect)) {
  1463.                 /* the first device with an intersection is the winner */
  1464.                 twp->gdRect = (*gdev)->gdRect;            
  1465.                 return;
  1466.             }
  1467.         }
  1468.         /* if we reach here, the window is completely off the screen */
  1469.     }
  1470.     /* screenBits is our default */
  1471.     twp->gdRect = screenBits.bounds;
  1472. }
  1473.  
  1474.  
  1475. /* test to see whether the window may need to be coerced to fit */
  1476.  
  1477. windtightfit(twp)
  1478. struct winds * twp;
  1479. {
  1480.     setgdrect(twp);
  1481.     if (twp->gdRect.right == 512)
  1482.         return(TRUE);
  1483.     else if (twp->gdRect.right == 640) {
  1484.         if (twp->fontsize == 16)
  1485.             return(TRUE);
  1486.     }
  1487.     return(FALSE);
  1488. }
  1489.  
  1490. /* set the emdp context window titles */
  1491.  
  1492. windowtitle(twp, passtr)
  1493. struct winds * twp;
  1494. Str255 * passtr;
  1495. {
  1496.     char macfile[256];
  1497.     FILE *textfp;
  1498.     int readcount;
  1499.     char filebuffer[514];
  1500.     
  1501.     SetWTitle(twp->emwindow, passtr);
  1502. #ifdef USETEXTWINDOWS
  1503.     /* give the text window the same name with ".text" appended */
  1504.     ptoc(passtr);
  1505.     sprintf(&macfile[0], "%s.edit", passtr);
  1506.     ctop(passtr);
  1507.     
  1508.     ctop(&macfile[0]);
  1509.     SetWTitle(twp->textwindow, &macfile[0]);
  1510. #define LOADTEXTWINDOWS
  1511. #ifdef LOADTEXTWINDOWS
  1512.     /* automagically load up the text window with the text */
  1513.     tesetsel( (long) 0, (long) (*twp->texthand)->teLength, twp->texthand);
  1514.     TEDelete(twp->texthand);
  1515.     textctlupd(twp);
  1516.     SelView(twp);
  1517.     
  1518.     textfp = fopen(&macfile[0], "r");
  1519.     if (textfp != NULL) { 
  1520.         while (TRUE) {
  1521.             readcount = fread(&filebuffer[0], 1, 512, textfp);
  1522.             if (readcount == 0) {
  1523.                 /* we've read the whole file */
  1524.                 break;
  1525.             }
  1526.             textwappend(&filebuffer[0], (long) readcount);
  1527.         }
  1528.         fclose(textfp);
  1529.     }
  1530. #endif
  1531. #endif
  1532. }
  1533.  
  1534.  
  1535.  
  1536. /* build a map of diacritical marks to handle spacing */
  1537.  
  1538. builddiacritics()
  1539. {
  1540.     register int count;             /* all purpose counter */
  1541.     
  1542.     for (count = 0; count < NOCHARS; count++)
  1543.         if (CharWidth(count) == 0)
  1544.             isdiacritic[count] = 1;
  1545. }
  1546.  
  1547.  
  1548. /* update the current color map to best available colors */
  1549.  
  1550. colorupd(twp)
  1551. struct winds * twp;
  1552. {
  1553.     RGBColor * srccolor = &twp->ibmcolormap.colors[0];
  1554.     RGBColor * matchcolor = &twp->colormap.colors[0];
  1555.     unsigned long colorindex;
  1556.     int count;
  1557.     
  1558.     if (!twp->color)
  1559.         return;
  1560.         
  1561.     for (count = 0; count++ < MAXCOLORS; srccolor++, matchcolor++) {
  1562.         colorindex = Color2Index(srccolor);
  1563.         Index2Color(colorindex, matchcolor);
  1564.     }
  1565. }
  1566.  
  1567.